/*
    Wild Flamenco metronome 0.5
    -
    By David Reguera Garcia - Dreg@fr33project.org -
    http://wildflamenco.blogspot.com/

    Copyright (C) <2011>  <David Reguera Garcia>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

*/


#include <stdlib.h>
#include <stdio.h>

#include <windows.h>

#include "resource.h"
#include "list.h"

#define MAX_BPM_ALLOWED 600
#define DEFAULT_BPM_STR "180"
#define DEFAULT_BPM atoi( DEFAULT_BPM_STR )
#define DEFAULT_COMPAS_STR "1"
#define DEFAULT_COMPAS atoi( DEFAULT_COMPAS_STR )
#define DEFAULT_BEATS_STR "12"
#define DEFAULT_BEATS atoi( DEFAULT_BEATS_STR )
#define DEFAULT_SAVE_TO_DISK_NAME "ownrythm.wldr"
#define MAX_COMPAS_ALLOWED 200
#define MAX_BEATS_ALLOWED 200

#define ConvertBPMToMS( bpm ) ( (double) 60000 / bpm )

typedef enum TYPE_SOUNDWLDR_e
{
    builtin,
    file

} TYPE_SOUNDWLDR_t;


typedef struct SOUND_BUILTIN_s
{
    LPSTR lpstr;
    char name[100];
    
} SOUND_BUILTIN_t;

typedef struct SOUND_FILE_s
{
    char path[MAX_PATH];
    
} SOUND_FILE_t;

typedef struct SOUNDS_s
{
    TYPE_SOUNDWLDR_t type;
    union
    {
        SOUND_BUILTIN_t builtin;
        SOUND_FILE_t file;

    } sound;
    
} SOUNDS_t;

typedef struct PATTERN_s
{
    SOUNDS_t ** sounds_array;
    int ct;
    int nr_elements;

} PATTERN_t;

void CALLBACK TimeProc( UINT uID, UINT uMsg, DWORD input, DWORD dw1, DWORD dw2 )
{     
    PATTERN_t * pattern;

    pattern = ( PATTERN_t * ) input;

    if ( pattern->sounds_array[pattern->ct]->type == builtin )
    {
        PlaySoundA
        ( 
            pattern->sounds_array[pattern->ct]->sound.builtin.lpstr, 
            NULL, 
            SND_MEMORY | SND_SYNC | SND_NODEFAULT 
        );
    }
    else
    {
        PlaySoundA
        (
            pattern->sounds_array[pattern->ct]->sound.file.path, 
            NULL, 
            SND_FILENAME | SND_SYNC 
        );
    }

    pattern->ct = (pattern->ct + 1) % pattern->nr_elements;
}


void StartStopTimer( BOOL start, PATTERN_t * pattern, unsigned int bpm )
{
    double ms;
    TIMECAPS tc;
    static MMRESULT timer_id = 0;
    static UINT resolution = 0;

    if ( timer_id )
        timeKillEvent( timer_id );
    
    if ( resolution )
        timeEndPeriod( resolution );

    if ( start )
    {
        ms = ConvertBPMToMS( bpm );
    
        timeGetDevCaps( & tc, sizeof( tc ) );
        resolution = tc.wPeriodMin;
    
        timeBeginPeriod( resolution );

        Sleep( 400 );
        timer_id = timeSetEvent( ms, resolution, TimeProc, (DWORD) pattern, TIME_PERIODIC );
    }
}

BOOL CatExtension( char * string, unsigned int size_string )
{
    if ( ( strlen( string ) + strlen( ".wldr" ) ) <= (size_string - 1) )
    {
        strcat( string, ".wldr" );
    }
    else
        return FALSE;

    return TRUE;
}

LIST_t list_sounds;
LIST_t list_wldrs;

BOOL GetTheResource(LPSTR lpName, LPSTR * lpRes ) 
{ 
    BOOL bRtn; 
    HANDLE hResInfo, hRes; 
    HINSTANCE hInst;

    hInst = GetModuleHandle( NULL );

    // Find the WAVE resource. 
    hResInfo = FindResourceA(hInst, lpName, "WAVE"); 
    if (hResInfo == NULL) 
        return FALSE; 

    // Load the WAVE resource. 
 
    hRes = LoadResource(hInst, hResInfo); 
    if (hRes == NULL) 
        return FALSE; 
 
    // Lock the WAVE resource and play it. 
 
    * lpRes = LockResource(hRes); 
    if (* lpRes != NULL) { 

//        UnlockResource(hRes); 
    } 
    else 
        bRtn = 0; 
 
    // Free the WAVE resource and return success or failure. 
 
   // FreeResource(hRes); 
    return bRtn; 
} 

char * builtin_sounds[] =
{
    "golpe", "palma", "silencio"
};

void InitSounds( HWND hDlg )
{
    SOUNDS_t * sound_node;
    int i;
    HANDLE hFind;
    WIN32_FIND_DATAA FindData;

    if ( ListCreate( & list_sounds ) )
    {
        hFind = FindFirstFileA( "*.wav", & FindData );
        if ( hFind != INVALID_HANDLE_VALUE ) 
        {
            if ( strlen( FindData.cFileName  ) <= ( sizeof( sound_node->sound.file.path ) - 1 ) )
            {
                do
                {
                    sound_node = calloc( 1, sizeof( * sound_node ) );
                    if ( sound_node != NULL )
                    {
                        sound_node->type = file;
                        
                        strcpy( sound_node->sound.file.path, FindData.cFileName );

                        if ( ListAdd( & list_sounds, sound_node ) == FALSE )
                            MessageBoxA( hDlg, " ERROR FILE", " ADD LIST", MB_OK );
                    }
                } while ( FindNextFile( hFind, & FindData ) != 0 );
            }
        }       

        sound_node = calloc( 1, sizeof( SOUNDS_t ) * ( sizeof( builtin_sounds ) / sizeof( * builtin_sounds ) ) );
        if ( sound_node != NULL )
        {
            for ( i = 0; i < sizeof( builtin_sounds ) / sizeof( * builtin_sounds ); i++ )
            {
                sound_node[i].type = builtin;
                strcpy( sound_node[i].sound.builtin.name, builtin_sounds[i] );
                if ( GetTheResource( sound_node[i].sound.builtin.name, & sound_node[i].sound.builtin.lpstr ) == FALSE )
                    MessageBoxA( hDlg, " ERROR BUILTIN", " NO RESOURCE", MB_OK );
    
                if ( ListAdd( & list_sounds, & sound_node[i] ) == FALSE )
                    MessageBoxA( hDlg, " ERROR BUILTIN", " ADD LIST", MB_OK );
            }
        }
        else
            MessageBoxA( hDlg, " ERROR BUILTIN", " NO MEMORY", MB_OK );
    }
}

void ShowSounds( HWND hDlg )
{
    int i;
    SOUNDS_t * sound_node;
    unsigned int nr_elements;
    char * entries = NULL;
    
    nr_elements = ListGetNrElements( & list_sounds );
    entries = calloc( 1, ( (MAX_PATH + 2) * nr_elements ) + 1 );

    if ( entries )
    {
        for ( i = 0; ; i++ )
        {
            sound_node = (SOUNDS_t *) ListGet( & list_sounds, i );
            if ( sound_node == NULL )
                break;
    
            if ( sound_node->type == builtin )
            {
                strcat( entries, sound_node->sound.builtin.name );
                strcat( entries, " - (builtin type)\r\n" );
            }
            else
            {
                strcat( entries, sound_node->sound.file.path );
                strcat( entries, "\r\n" );
            }
        }

        SetDlgItemTextA(hDlg,IDC_EDIT2, entries);
    }
}

typedef struct WLDR_BUILTIN_s
{
    char name[100];
    
} WLDR_BUILTIN_t;

typedef struct WLDR_FILE_s
{
    char path[MAX_PATH];
    
} WLDR_FILE_t;

typedef struct WLDR_s
{
    TYPE_SOUNDWLDR_t type;
    union
    {
        WLDR_BUILTIN_t builtin;
        WLDR_FILE_t file;

    } wldr;

    unsigned int nr_beats;
    unsigned int nr_compas;
    SOUNDS_t ** sounds;
    
} WLDR_t;

typedef struct WLDRS_BUILTINS_s
{
    char * wldr_name;
    char * name[100];
    unsigned int nr_beats;
    unsigned int nr_compas;
    
} WLDRS_BUILTINS_t;

typedef enum BUILTIN_SOUNDS_INDEX_e
{
    igolpe = 0,
    ipalma,
    isilencio

} BUILTIN_SOUNDS_INDEX_t;



void ShowWldrs( HWND hDlg )
{
    int i;
    WLDR_t * wldr_node;
    WLDR_t wldr_aux;
    unsigned int nr_elements;
    HWND hwndList;
    int pos;
    char aux[100];

    nr_elements = ListGetNrElements( & list_wldrs );

    hwndList = GetDlgItem(hDlg, IDC_LIST1 );  

    for ( i = 0; i < nr_elements; i++ )
    {
        wldr_node = (WLDR_t *) ListGet( & list_wldrs, i );
        if ( wldr_node == NULL )
            break;

        if ( wldr_node->type == builtin )
        {
            strcpy( aux, wldr_node->wldr.builtin.name );
            strcat( aux, " - (builtin type)" );
            pos = (int)SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM) aux ); 
        }
        else
            pos = (int)SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM) wldr_node->wldr.file.path ); 

        SendMessage(hwndList, LB_SETITEMDATA, pos, (LPARAM) i); 
    }

    SendMessage(hwndList, LB_SETCURSEL, 0, 0); 
}

void InitWldrs( HWND hDlg )
{
    HANDLE hFind;
    WIN32_FIND_DATAA FindData;
    WLDR_t * wldr;
    int i, j, k, h;
    FILE * read_file;
    WLDRS_BUILTINS_t wldrs_builtins[] = 
    {
        {
            "Buleria",
            { 
                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma]
            },
            12,
            1
        },  
        {
            "Buleria 4 compas",
            { 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[isilencio], 

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma]
            },
            12,
            4
        },  
        {
            "Solea",
            { 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[igolpe],

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[igolpe], 

                builtin_sounds[ipalma],
                builtin_sounds[igolpe], 

                builtin_sounds[ipalma],
                builtin_sounds[igolpe],

                builtin_sounds[ipalma],
                builtin_sounds[igolpe]
            },
            12,
            1
        },
        {
            "Tango",
            { 
                builtin_sounds[isilencio],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma]
            },
            4,
            1
        },
        {
            "Rumba",
            { 
                builtin_sounds[isilencio],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma]
            },
            4,
            1
        },
        {
            "Sevillana",
            { 
                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma]
            },
            3,
            1
        },
        {
            "Fandango",
            { 
                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma]
            },
            12,
            1
        },
        {
            "Alegria",
            { 
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[igolpe],

                builtin_sounds[ipalma],
                builtin_sounds[ipalma],
                builtin_sounds[igolpe], 

                builtin_sounds[ipalma],
                builtin_sounds[igolpe], 

                builtin_sounds[ipalma],
                builtin_sounds[igolpe],

                builtin_sounds[ipalma],
                builtin_sounds[igolpe]
            },
            12,
            1
        },
        {
            "Siguiriya",
            { 
                builtin_sounds[igolpe], 
                builtin_sounds[ipalma],

                builtin_sounds[igolpe],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe],
                builtin_sounds[ipalma],
                builtin_sounds[ipalma],

                builtin_sounds[igolpe], 
                builtin_sounds[ipalma]
            },
            12,
            1
        }
    };
    SOUNDS_t * sound_node;
    SOUNDS_t ** sound_aux;
    SOUNDS_t * sound_array;

    if ( ListCreate( & list_wldrs ) )
    {
        wldr = calloc( 1, sizeof( * wldr ) * ( sizeof( wldrs_builtins ) / sizeof( * wldrs_builtins ) ) );
        if ( wldr != NULL )
        {
            for ( i = 0; i < sizeof( wldrs_builtins ) / sizeof( * wldrs_builtins ); i++ )
            {
                wldr[i].type = builtin;
                wldr[i].nr_beats = wldrs_builtins[i].nr_beats; 
                wldr[i].nr_compas = wldrs_builtins[i].nr_compas; 

                strcpy( wldr[i].wldr.builtin.name, wldrs_builtins[i].wldr_name );

                wldr[i].sounds = calloc( 1, sizeof( * wldr->sounds ) * ( wldrs_builtins[i].nr_compas * wldrs_builtins[i].nr_beats ) );
                if ( wldr[i].sounds != NULL )
                {
                    for ( j = 0; j  < (wldrs_builtins[i].nr_compas * wldrs_builtins[i].nr_beats); j++ )
                    {
                        k = 0;
                        while ( 1 )
                        {
                            sound_node = (SOUNDS_t *) ListGet( & list_sounds, k );
                            if ( sound_node->type == builtin )
                            {
                                if ( strcmp( sound_node->sound.builtin.name, wldrs_builtins[i].name[j] ) == 0 )
                                    break;
                            }
                            
                            k++;
                        }
                        wldr[i].sounds[j] = sound_node;
                    }

                    if ( ListAdd( & list_wldrs, & wldr[i] ) == FALSE )
                        MessageBoxA( hDlg, " ERROR FILE", " ADD LIST", MB_OK );
            
                }
            }
        }

        hFind = FindFirstFileA( "*.wldr", & FindData );
        if ( hFind != INVALID_HANDLE_VALUE ) 
        {
            if ( strlen( FindData.cFileName  ) <= ( sizeof( wldr->wldr.file.path ) - 1 ) )
            {
                do
                {
                    read_file = fopen( FindData.cFileName, "rb" );
                    if ( read_file != NULL )
                    {
                        fseek( read_file, 0L, SEEK_SET );
                        wldr = calloc( 1, sizeof( * wldr ) );
                        if ( wldr != NULL )
                        { 
                            if ( fread( wldr, sizeof( * wldr ), 1, read_file ) == 1 )
                            {
                                strcpy( wldr->wldr.file.path, FindData.cFileName );
                                sound_aux = calloc( 1, sizeof( * sound_aux ) * ( wldr->nr_beats * wldr->nr_compas ) );
                                if ( sound_aux != NULL )
                                {
                                    wldr->sounds = sound_aux;

                                    sound_array = calloc( 1, sizeof( * sound_array ) * ( wldr->nr_beats * wldr->nr_compas ) );
                                    if ( sound_array != NULL )
                                    {
                                        if ( fread( sound_array, sizeof( * sound_array ) * ( wldr->nr_beats * wldr->nr_compas) , 1, read_file ) == 1 )
                                        {
                                            for ( h = 0; h < wldr->nr_beats * wldr->nr_compas; h++ )
                                            {
                                                k = 0;
                                                while ( 1 )
                                                {
                                                    sound_node = (SOUNDS_t *) ListGet( & list_sounds, k );
                                                    if ( sound_node->type == builtin )
                                                    {
                                                        if ( strcmp( sound_node->sound.builtin.name, sound_array[h].sound.builtin.name ) == 0 )
                                                            break;
                                                    }
                                                    else
                                                    {
                                                        if ( strcmp( sound_node->sound.file.path, sound_array[h].sound.file.path ) == 0 )
                                                            break;
                                                    }
                                                    
                                                    k++;
                                                }
                                                
                                                wldr->sounds[h] = sound_node; 
                                            }

                                            if ( ListAdd( & list_wldrs, wldr ) == FALSE )
                                                MessageBoxA( hDlg, " ERROR FILE", " ADD LIST", MB_OK );
                                        }

                                        
                                    }
                                }
                            }
                        }

                        fclose( read_file );
                    }
                } while ( FindNextFile( hFind, & FindData ) != 0 );
            }
        }       
    }
}


BOOL CALLBACK AppDlgProc2(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch( uMsg )
    {
        case WM_INITDIALOG: 
            return 1;
        break;

        case WM_COMMAND:
            switch(wParam)
            {
                case IDOK:
                case IDCANCEL:
                    StartStopTimer( FALSE, NULL, 0 );

                    EndDialog(hDlg, 0);
                break;
            }
        break;
    }

    return 0;
}

BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    char bpm_str[100];
    char nr_compas_str[100];
    char nr_beats_str[100];
    unsigned int bpm;
    unsigned int nr_compas;
    unsigned int nr_beats;
    char save_file_str[MAX_PATH];
    char * extension;
    static PATTERN_t pattern;
    int i;
    HWND hwndList;
    int lbItem;
    WLDR_t * wldr_node;
    WLDR_t wldr_aux;
    FILE * save_file;

    memset( nr_compas_str, 0, sizeof( nr_compas_str ) );
    memset( bpm_str, 0, sizeof( bpm_str ) );

    switch( uMsg )
    {
        case WM_INITDIALOG: 
            SetClassLongPtr(hDlg, GCLP_HICON, (long)LoadIcon( GetModuleHandle( NULL ), MAKEINTRESOURCE(IDI_ICON1)));
            SetDlgItemTextA(hDlg,IDC_EDIT1,DEFAULT_BPM_STR);
            SetDlgItemTextA(hDlg,IDC_EDIT3,DEFAULT_COMPAS_STR);
            SetDlgItemTextA(hDlg,IDC_EDIT5,DEFAULT_BEATS_STR);
            SetDlgItemTextA(hDlg,IDC_EDIT4,DEFAULT_SAVE_TO_DISK_NAME);

            InitSounds( hDlg );
            ShowSounds( hDlg );

            InitWldrs( hDlg );
            ShowWldrs( hDlg );
        
            return 1;

        break;

        case WM_COMMAND:
            switch(wParam)
            {
                case IDC_BUTTON1:
                    ShellExecute(NULL, "open", "http://wildflamenco.blogspot.com/", NULL, NULL, SW_SHOWNORMAL);
                break;
            
                case IDSTARTT:
                    StartStopTimer( FALSE, NULL, 0 );
                
                    if ( GetWindowTextA( GetDlgItem(hDlg, IDC_EDIT1), bpm_str, sizeof(bpm_str) - 1) == 0 )
                        bpm = DEFAULT_BPM; 
                    else
                    {
                        bpm = atoi( bpm_str );
                        if ( bpm >= MAX_BPM_ALLOWED || bpm == 0 )
                            bpm = DEFAULT_BPM; 
                    }
                    itoa( bpm, bpm_str, 10 );
                    SetDlgItemTextA(hDlg,IDC_EDIT1,bpm_str);

                    hwndList = GetDlgItem(hDlg, IDC_LIST1); 
                    lbItem = (int)SendMessage(hwndList, LB_GETCURSEL, 0, 0); 
                    i = (int)SendMessage(hwndList, LB_GETITEMDATA, lbItem, 0);

                    wldr_node = (WLDR_t *) ListGet( & list_wldrs, i );
                    
                    pattern.ct = 0;
                    pattern.nr_elements = wldr_node->nr_beats * wldr_node->nr_compas;
                    pattern.sounds_array = wldr_node->sounds;

                    //pattern.sounds_array[2] = ListGet( & list_sounds, 5 );
                    
                    StartStopTimer( TRUE, & pattern, bpm );
                break;
            
                case IDC_BUTTON2:
                    StartStopTimer( FALSE, NULL, 0 );
                
                    if ( GetWindowTextA( GetDlgItem(hDlg, IDC_EDIT3), nr_compas_str, sizeof(nr_compas_str) - 1) == 0 )
                        nr_compas = DEFAULT_COMPAS;
                    else
                    {
                        nr_compas = atoi( nr_compas_str );
                        
                        if ( nr_compas > MAX_COMPAS_ALLOWED || nr_compas == 0 )
                            nr_compas = DEFAULT_COMPAS;
                    }
                    itoa( nr_compas, nr_compas_str, 10 );
                    SetDlgItemTextA(hDlg,IDC_EDIT3,nr_compas_str);

                    if ( GetWindowTextA( GetDlgItem(hDlg, IDC_EDIT5), nr_beats_str, sizeof(nr_beats_str) - 1) == 0 )
                        nr_beats = DEFAULT_BEATS;
                    else
                    {
                        nr_compas = atoi( nr_beats_str );
                        
                        if ( nr_beats > MAX_BEATS_ALLOWED || nr_beats == 0 )
                            nr_beats = DEFAULT_BEATS;
                    }
                    itoa( nr_beats, nr_beats_str, 10 );
                    SetDlgItemTextA(hDlg,IDC_EDIT5,nr_beats_str);

                    DialogBoxParam( NULL, MAKEINTRESOURCE( IDD_DIALOG3 ), hDlg, AppDlgProc2, 0 );
                break;

                case IDC_BUTTON3:
                    DialogBoxParam( NULL, MAKEINTRESOURCE( IDD_DIALOG3 ), hDlg, AppDlgProc2, 0 );
                break;

                case IDC_BUTTON4:
                    StartStopTimer( FALSE, NULL, 0 );
                
                    if ( GetWindowTextA( GetDlgItem(hDlg, IDC_EDIT4), save_file_str, sizeof(save_file_str) - 1) == 0 )
                        strcpy( save_file_str, DEFAULT_SAVE_TO_DISK_NAME );
                    else
                    {
                        extension = strrchr( save_file_str, '.' );
                        if ( extension == NULL )
                        {
                            if ( CatExtension( save_file_str, sizeof( save_file_str ) ) == FALSE )
                                strcpy( save_file_str, DEFAULT_SAVE_TO_DISK_NAME );
                        }
                        else
                        {
                            if ( strcmpi( extension, ".wldr" ) != 0 )
                            {
                                if ( CatExtension( save_file_str, sizeof( save_file_str ) ) == FALSE )
                                    strcpy( save_file_str, DEFAULT_SAVE_TO_DISK_NAME );
                            }
                        }

                    }
                    SetDlgItemTextA(hDlg,IDC_EDIT4,save_file_str);

                    hwndList = GetDlgItem(hDlg, IDC_LIST1); 
                    lbItem = (int)SendMessage(hwndList, LB_GETCURSEL, 0, 0); 
                    i = (int)SendMessage(hwndList, LB_GETITEMDATA, lbItem, 0);

                    wldr_node = (WLDR_t *) ListGet( & list_wldrs, i );

                    save_file = fopen( save_file_str, "rb+" );
                    if ( save_file == NULL )
                    {
                        save_file = fopen( save_file_str, "wb" );
                        fseek( save_file, 0L, SEEK_SET );
                
                        memcpy( & wldr_aux, wldr_node, sizeof( wldr_aux ) );

                        if ( wldr_aux.type == builtin )
                        {
                            wldr_aux.type = file;
                            strcpy( wldr_aux.wldr.file.path, save_file_str );
                        }
                        if ( fwrite( & wldr_aux, sizeof( wldr_aux ), 1, save_file ) != 1 )
                            MessageBoxA( hDlg, " Error writing file", " Error writing file", MB_OK );

                        for ( i = 0; i < ( wldr_aux.nr_compas * wldr_aux.nr_beats ); i++ )
                        {
                            if ( fwrite( wldr_aux.sounds[i], sizeof( SOUNDS_t ), 1, save_file ) != 1 )
                            {
                                MessageBoxA( hDlg, " Error writing file", " Error writing file", MB_OK );
                                break;
                            }
                        }

                        fclose( save_file );

                        MessageBoxA( hDlg, " Saved!", " Saved!", MB_OK );
                       
                    }
                    else
                    {
                        MessageBoxA( hDlg, " Error: The file exist! change the name", " Error: The file exist! change the name", MB_OK );
                        fclose( save_file );
                    }
                break;
            
                case IDSTOPP:
                    StartStopTimer( FALSE, NULL, 0 );
                break;

                case IDC_BUTTON5:
                    ShellExecute(NULL, "open", "http://www.youtube.com/watch?v=MQE9EWnvT08", NULL, NULL, SW_SHOWNORMAL);
                break;

                case IDC_BUTTON6:
                    ShellExecute(NULL, "open", "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TACJDTH6F6KY4&item_name=wildflamenco&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted", NULL, NULL, SW_SHOWNORMAL);
                break;
            
                case IDCANCEL:
                    StartStopTimer( FALSE, NULL, 0 );

                    srand(time(NULL));
                    int r = rand() % 100;
                    // I dont want a spam overflow x)
                    if ( r < 3 )
                        ShellExecute(NULL, "open", "http://wildflamenco.blogspot.com/", NULL, NULL, SW_SHOWNORMAL);

                  EndDialog(hDlg, 0);
                break;
            }
        break;
    }

    return 0;
}


int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{

    
    DialogBoxParam( hThisInstance, MAKEINTRESOURCE( IDD_DIALOG1 ), 0, AppDlgProc, 0 );

    return 0;
}

